package top.coolrainly.module.resource.service.group;

import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import top.coolrainly.module.resource.controller.admin.group.vo.*;
import top.coolrainly.module.resource.convert.content.ResourceContentConvert;
import top.coolrainly.module.resource.dal.dataobject.group.ResourceGroupDO;
import top.coolrainly.module.resource.dal.dataobject.content.ResourceContentDO;
import top.coolrainly.framework.common.pojo.PageResult;
import top.coolrainly.framework.common.pojo.PageParam;
import top.coolrainly.framework.common.util.object.BeanUtils;

import top.coolrainly.module.resource.dal.mysql.group.ResourceGroupMapper;
import top.coolrainly.module.resource.dal.mysql.content.ResourceContentMapper;

import static top.coolrainly.framework.common.exception.util.ServiceExceptionUtil.exception;
import static top.coolrainly.module.resource.enums.ErrorCodeConstants.*;

/**
 * Web3D 资源 分组 Service 实现类
 *
 * @author CoolRainLy
 */
@Service
@Validated
public class ResourceGroupServiceImpl implements ResourceGroupService {

    @Resource
    private ResourceGroupMapper groupMapper;
    @Resource
    private ResourceContentMapper contentMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createGroup(ResourceGroupSaveReqVO createReqVO) {
        // 插入
        ResourceGroupDO group = BeanUtils.toBean(createReqVO, ResourceGroupDO.class);
        groupMapper.insert(group);

        // 插入子表
        if (createReqVO.getContents() != null) {
            createContentList(group.getId(), createReqVO.getContents());
        }
        // 返回
        return group.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateGroup(ResourceGroupSaveReqVO updateReqVO) {
        // 校验存在
        validateGroupExists(updateReqVO.getId());
        // 更新
        ResourceGroupDO updateObj = BeanUtils.toBean(updateReqVO, ResourceGroupDO.class);
        groupMapper.updateById(updateObj);

        // 更新子表
        if (updateReqVO.getContents() != null) {
            updateContentList(updateReqVO.getId(), updateReqVO.getContents());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteGroup(Long id) {
        // 校验存在
        validateGroupExists(id);
        // 删除
        groupMapper.deleteById(id);

        // 删除子表
        deleteContentByGroupId(id);

        // 删除子分组
        List<ResourceGroupDO> children = groupMapper.selectList(ResourceGroupDO::getParent, id);
        children.forEach((group) -> {
            deleteGroup(group.getId());
        });
    }

    private void validateGroupExists(Long id) {
        if (groupMapper.selectById(id) == null) {
            throw exception(GROUP_NOT_EXISTS);
        }
    }

    @Override
    public ResourceGroupDO getGroup(Long id) {
        return groupMapper.selectById(id);
    }

    @Override
    public PageResult<ResourceGroupDO> getGroupPage(ResourceGroupPageReqVO pageReqVO) {
        return groupMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ResourceGroupTreeRespVO> getGroupTreeList(Integer type) {
        // 获取分组
        List<ResourceGroupDO> groupList = groupMapper.selectListByType(type);

        // 构建分组树
        Map<Long, ResourceGroupTreeRespVO> groupMap = new HashMap<>();
        List<ResourceGroupTreeRespVO> rootGroups = new ArrayList<>();

        // 初始化分组映射
        for (ResourceGroupDO group : groupList) {
            ResourceGroupTreeRespVO groupVO = BeanUtils.toBean(
                    group,
                    ResourceGroupTreeRespVO.class
            );
            groupVO.setGroupChild(new ArrayList<>());

            groupMap.put(group.getId(), groupVO);

            if (group.getParent() == null || group.getParent() == 0) {
                rootGroups.add(groupVO);
            }
        }

        // 构建分组树结构
        for (ResourceGroupDO group : groupList) {
            if (group.getParent() != null && group.getParent() != 0) {
                ResourceGroupTreeRespVO parentGroup = groupMap.get(group.getParent());
                if (parentGroup != null) {
                    parentGroup.getGroupChild().add(groupMap.get(group.getId()));
                }
            }
        }

        return rootGroups;
    }

    // ==================== 子表（Web3D 资源 内容） ====================

    @Override
    public List<ResourceGroupContentRespVO> getContentTreeList(Integer type) {
        // 获取分组和内容列表
        List<ResourceGroupDO> groupList = groupMapper.selectListByType(type);
        List<ResourceContentDO> contentList = contentMapper.selectListByType(type);

        // 构建分组树
        Map<Long, ResourceGroupContentRespVO> groupMap = new HashMap<>();
        List<ResourceGroupContentRespVO> rootGroups = new ArrayList<>();

        // 初始化分组映射
        for (ResourceGroupDO group : groupList) {
            ResourceGroupContentRespVO groupVO = BeanUtils.toBean(
                    group,
                    ResourceGroupContentRespVO.class
            );
            groupVO.setGroupChild(new ArrayList<>());
            groupVO.setContentChild(new ArrayList<>());

            groupMap.put(group.getId(), groupVO);

            if (group.getParent() == null || group.getParent() == 0) {
                rootGroups.add(groupVO);
            }
        }

        // 构建分组树结构
        for (ResourceGroupDO group : groupList) {
            if (group.getParent() != null && group.getParent() != 0) {
                ResourceGroupContentRespVO parentGroup = groupMap.get(group.getParent());
                if (parentGroup != null) {
                    parentGroup.getGroupChild().add(groupMap.get(group.getId()));
                }
            }
        }

        // 将内容分配到对应的分组
        for (ResourceContentDO content : contentList) {
            ResourceGroupContentRespVO groupVO = groupMap.get(content.getGroupId());
            if (groupVO != null) {
                groupVO.getContentChild().add(ResourceContentConvert.INSTANCE.convert(content));
            }
        }

        return rootGroups;
    }

    private void createContentList(Long groupId, List<ResourceContentDO> list) {
        list.forEach(o -> o.setGroupId(groupId));
        contentMapper.insertBatch(list);
    }

    private void updateContentList(Long groupId, List<ResourceContentDO> list) {
        deleteContentByGroupId(groupId);
		list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下：1）id 冲突；2）updateTime 不更新
        createContentList(groupId, list);
    }

    private void deleteContentByGroupId(Long groupId) {
        contentMapper.deleteByGroupId(groupId);
    }

}